#include "main.h"
#include "util_crc.h"
#include "util_cmd.h"
#include "util_str.h"
#include "util_mem.h"
#include "delay.h"
#include "uart_peripheral.h"
#include "uart_cmd.h"
#include "stdio.h"
#include "string.h"
#include "NuMicro.h"
#include "yx031_app.h"

char *yx031Heap = "yx031Heap";
#define HEAP_1_SIZE 16384
static uint8_t heap1[HEAP_1_SIZE];
#define FRAME_SEND_SEQ(s,f) do{ \
		if(s->frame.dataBit == 16){ \
			if(f == 0){\
			sendFrameSqe(s->frame.dataBit,s->frame.data16,s->frame.pwm16len,s->frame.b_data16); \
			}\
			else{\
			sendFrameSqe(s->frame.dataBit,s->frame.data16_1,s->frame.pwm16len,s->frame.b_data16_1); \
			}\
		}\
		else if(s->frame.dataBit == 12) { \
			if(f == 0){\
			sendFrameSqe(s->frame.dataBit,s->frame.data12,s->frame.pwm12len,s->frame.b_data12); \
			}\
			else{\
			sendFrameSqe(s->frame.dataBit,s->frame.data12_1,s->frame.pwm12len,s->frame.b_data12_1); \
			}\
		} \
	} while(0)

struct ICParameter {
    uint8_t *REG0;
	uint8_t *REG0_2;
    uint8_t *REG1;
    uint8_t *REG2;
    uint8_t *REG3;
    uint8_t *REG4;
};
struct uartParameter {
    uint32_t baudrate;
    uint8_t stopbit;
    uint8_t intervalbit;
};

struct FrameTaskParameter {
	uint8_t dataBit;
    uint16_t time;
	 uint16_t newTime;
	
	uint16_t pwm16len;
	uint16_t pwm12len;
	
	uint8_t *data12;
	uint8_t *data16;

    uint8_t *data12_1;
    uint8_t *data16_1;
	
	uint8_t *b_data12;
	uint8_t *b_data16;

    uint8_t *b_data12_1;
    uint8_t *b_data16_1;
};
struct YX031ManagerType
{
	UART_PAR Uartpar;
    uint8_t UARTDoubleComEnable;

    struct ICParameter ICParameter;
    struct uartParameter uartParameter1;
    struct uartParameter uartParameter2;
    struct uartParameter uartParameter3;
	
	struct FrameTaskParameter frame;

	uint8_t LP_EN;
	uint32_t pdTime;

    uint8_t initDelayT1;
    uint8_t initDelayT2;
    uint8_t initDelayT3;
    uint8_t initDelayT4;

    uint8_t F3_T0;
    uint8_t F3_T1;
    uint8_t t_time;
    uint8_t brightnessTime;

    uint16_t init_rep;
    uint16_t chipNum;

    uint8_t satrtByte1;
    uint8_t satrtByte2;
    uint8_t *vsyncSeq;
    uint8_t vsyncLen;
    uint8_t *sendBrightnessBit16;
    uint8_t bit16Len;
    uint8_t *sendBrightnessBit12;
    uint8_t bit12Len;
	
	uint8_t *cache;
};

static struct YX031ManagerType *sManager = NULL;

static uint8_t T_offset = 5;

static char *sCmdYX031 = "yx031";

static char *sParInit = "init";
static char *sParFrame = "frame";
static char *sPar16bit = "16bit";
static char *sPar12bit = "12bit";

static char *sParTime = "time";
static char *sParREG = "reg";
static char *sParInterface = "interface";
static char *sParDouble = "double";
static char *sParLowIQ = "lowiq";


static char *sPar2Set = "set";
static char *sPar2Get = "get";
static char *sPar2send = "send";

static char *sPar2SISO = "siso";
static char *sPar2ABB = "abb";
static char *sPar21p1b = "1p1b";
static char *sPar23p1b = "3p1b";

static TaskHandle_t frameTaskHandle = NULL;
static TaskHandle_t frameTimeHandle = NULL;
static EventGroupHandle_t eventGroup = NULL;
static TimerHandle_t timerHandle = NULL;

#define YX031_EVENT_FLASH	    (0x01 << 1)


uint32_t YX031UartSetPar(UART_PAR par)
{
	if(sManager->Uartpar == par){return 0;}
    uint32_t intervalTime = 0;
    switch (par)
    {
    case PAR1:
        UartSetBaud(UART_COM2, sManager->uartParameter1.baudrate);
        UartSetSopbit(UART_COM2, sManager->uartParameter1.stopbit);
        UartSetBaud(UART_COM3, sManager->uartParameter1.baudrate);
        UartSetSopbit(UART_COM3, sManager->uartParameter1.stopbit);
        intervalTime = sManager->uartParameter1.intervalbit*(sManager->uartParameter1.baudrate/1000000);
        break;
    case PAR2:
        UartSetBaud(UART_COM2, sManager->uartParameter2.baudrate);
        UartSetSopbit(UART_COM2, sManager->uartParameter2.stopbit);
        UartSetBaud(UART_COM3, sManager->uartParameter2.baudrate);
        UartSetSopbit(UART_COM3, sManager->uartParameter2.stopbit);
        intervalTime = sManager->uartParameter2.intervalbit*(sManager->uartParameter2.baudrate/1000000);
        break;
    case PAR3:
        UartSetBaud(UART_COM2, sManager->uartParameter3.baudrate);
        UartSetSopbit(UART_COM2, sManager->uartParameter3.stopbit);
        UartSetBaud(UART_COM3, sManager->uartParameter3.baudrate);
        UartSetSopbit(UART_COM3, sManager->uartParameter3.stopbit);
        intervalTime = sManager->uartParameter3.intervalbit*(sManager->uartParameter3.baudrate/1000000);
        break;
    default:
        break;
    }
	sManager->Uartpar = par;
    return intervalTime;
}

void YX031UartsendPDMA(uint8_t *data, uint16_t len, UART_PAR par,uint8_t *data2)
{
    uint32_t  intervalTime = YX031UartSetPar(par);

    if(sManager->UARTDoubleComEnable == 0)
    {
        UartRawSendPDMA(UART_COM2, data, len);    
    }
    else
    {
		if(data[1] == 0x40 &&len == 4){
			UartRawSendPDMA(UART_COM2, data, len);
			UartRawSendPDMA(UART_COM3, data2, len);
		}
		else{
			UartRawSendPDMA(UART_COM2, data, len);
			UartRawSendPDMA(UART_COM3, data2, len);		
		}
    }
	switch (par)
	{
	case PAR1:
		delayUs(len*10*1000000/sManager->uartParameter1.baudrate);
		break;
	case PAR2:
		delayUs(len*10*1000000/sManager->uartParameter2.baudrate-T_offset);
		break;
	case PAR3:
		delayUs(len*10*1000000/sManager->uartParameter3.baudrate-T_offset);
		break;
	default:
        break;
	}
}

void sendOneInitSEQ()
{
        YX031UartsendPDMA(&(sManager->satrtByte1), 1, PAR1,&(sManager->satrtByte1));
        delayUs(sManager->initDelayT1-T_offset);
        YX031UartsendPDMA(sManager->ICParameter.REG4, 4,PAR1,sManager->ICParameter.REG4);
        delayUs(sManager->initDelayT2-T_offset);
        YX031UartsendPDMA(sManager->ICParameter.REG0, 4,PAR1,sManager->ICParameter.REG0_2);
        delayUs(sManager->initDelayT3-2*T_offset);
        for (int j = 0; j < 5; j++)
        {
            YX031UartsendPDMA(&(sManager->satrtByte2), 1, PAR2,&(sManager->satrtByte2));
//			delayUs(sManager->initDelayT4-T_offset);
        }  
		delayUs(sManager->t_time-T_offset);
}

void sendVSYNC()
{
    YX031UartsendPDMA(sManager->vsyncSeq, sManager->vsyncLen, PAR3,sManager->vsyncSeq);
}

void changeChar(char *p,uint16_t len,char *c)
{
	for(int i=0;i<len/12;i++)
	{
		for(int j=0;j<12;j++){
			c[i*12+j] = p[len-(i+1)*12+j];
		}
	}
}
uint8_t addchar(char *p,uint16_t len,char add,uint16_t position,uint16_t num)
{
	for (int i = len; i >= position; i--) {
		p[i+num] = p[i];
	}
	for (int i = 0; i<num; i++){
		p[position+i] = add;
	}
	return len+num;
} 
uint16_t brightnessDataCap(uint8_t dataBit,uint16_t sdataLength,uint8_t *sdata,uint8_t *edata,uint16_t model)
{
    uint16_t data,data1,data2,data3,data4,data5;
    uint16_t i = 0;
    if(dataBit == 16)
    {
        for(i = 0; i< sdataLength/4 ; i++)
        {
			data = StrGetHex((char *)sdata, 0, 4);
            edata[2*i+0] = (data >> 8) & 0xFF;
            edata[2*i+1] = data & 0xFF;
			sdata = sdata+4;
        }
        return sdataLength/2;
    }
    else if(dataBit == 12)
    {
		if(model != 0){
			for(i = 0; i< sdataLength/24 ; i++)
			{
				data = StrGetHex((char *)sdata, 0, 4);
				data1 = StrGetHex((char *)sdata, 4, 8);
				data2 = StrGetHex((char *)sdata, 8, 12);
				data3 = StrGetHex((char *)sdata, 12, 16);
				data4 = StrGetHex((char *)sdata, 16, 20);
				data5 = StrGetHex((char *)sdata, 20, 24);
				edata[9*i+0] = (data >> 4) & 0xFF;
				edata[9*i+1] = (data & 0x0F)|((data1>>4)&0xF0);
				edata[9*i+2] = data1 & 0xFF;
				edata[9*i+3] = (data2 >> 4) & 0xFF;
				edata[9*i+4] = (data2 & 0x0F)| ((data3>>4)&0xF0);
				edata[9*i+5] = data3 &0xFF;
				edata[9*i+6] = (data4 >> 4) & 0xFF;
				edata[9*i+7] = (data4 & 0x0F)|((data5>>4)&0xF0);
				edata[9*i+8] = data5 & 0xFF;			
				sdata =sdata+24;
			}
			return  sdataLength*9/24;
		}
		else{
			for(i = 0; i< sdataLength/12 ; i++)
			{
				data = StrGetHex((char *)sdata, 0, 4);
				data1 = StrGetHex((char *)sdata, 4, 8);
				data2 = StrGetHex((char *)sdata, 8, 12);
				edata[5*i+0] = (data >> 4) & 0xFF;
				edata[5*i+1] = (data & 0x0F)|((data1>>4)&0xF0);
				edata[5*i+2] = data1 & 0xFF;
				edata[5*i+3] = (data2 >> 4) & 0xFF;
				edata[5*i+4] = (data2 & 0x0F);
				sdata =sdata+12;
			}
			return  sdataLength*5/12;		
		}
    }
	return 0;
}
void setBrightness(uint8_t dataBit, uint8_t *sdata,uint16_t sdataLength ,uint8_t frameId ,uint8_t model)
{
	uint8_t *pwmdata,*b_pwmdata;
	char add = '0';
	uint16_t sdataLength_1 =sdataLength;
	if(frameId == 0 && dataBit == 16){pwmdata = sManager->frame.data16;b_pwmdata = sManager->frame.b_data16;}
	else if(frameId == 1 && dataBit == 16){pwmdata = sManager->frame.data16_1;b_pwmdata = sManager->frame.b_data16_1;}
	else if(frameId == 0 && dataBit == 12){pwmdata = sManager->frame.data12;b_pwmdata = sManager->frame.b_data12;}
	else if(frameId == 1 && dataBit == 12){pwmdata = sManager->frame.data12_1;b_pwmdata = sManager->frame.b_data12_1;}
	else{UartPrintf(UART_COM1, "set brightness err\r\n");}
	changeChar((char *)sdata,sdataLength,(char *)sManager->cache);
	if(model == 0){;}
	else if(model == 1){;}
	else if(model == 2){
		sdataLength = addchar((char *)sdata,sdataLength,add,sdataLength/2,12);
		sdataLength = addchar((char *)sdata,sdataLength,add,sdataLength,12);
		sdataLength_1 = addchar((char *)sManager->cache,sdataLength_1,add,sdataLength_1/2,12);
		sdataLength_1 = addchar((char *)sManager->cache,sdataLength_1,add,sdataLength_1,12);
	}
	else if(model == 3){
		sdataLength = addchar((char *)sdata,sdataLength,add,sdataLength/2,12*3);
		sdataLength = addchar((char *)sdata,sdataLength,add,sdataLength,12);
		sdataLength_1 = addchar((char *)sManager->cache,sdataLength_1,add,sdataLength_1/2,12*3);
		sdataLength_1 = addchar((char *)sManager->cache,sdataLength_1,add,sdataLength_1,12);	
	}
	else{}
	if(dataBit == 16){sManager->frame.pwm16len = brightnessDataCap(dataBit,sdataLength,sdata,pwmdata,model);}
	else if(dataBit == 12){sManager->frame.pwm12len = brightnessDataCap(dataBit,sdataLength,sdata,pwmdata,model);}
	brightnessDataCap(dataBit,sdataLength,sManager->cache,b_pwmdata,model);
	UartPrintf(UART_COM1,"uart2:");
	for(int i=0;i<sdataLength;i++){UartPrintf(UART_COM1,"%c",(char)sdata[i]);}
	UartPrintf(UART_COM1,"\r\n uart3:");
	for(int i=0;i<sdataLength;i++){UartPrintf(UART_COM1,"%c",(char)sManager->cache[i]);}	
	for(int i = 0;i<3072;i++){sManager->cache[i]=0;}
	UartPrintf(UART_COM1,"\r\n");
}

void sendBrightness(uint8_t dataBit, uint8_t *data, uint16_t dataLength,uint8_t *data2)
{
    uint16_t i = 0;
    switch (dataBit)
    {
    case 16:
        YX031UartsendPDMA(sManager->sendBrightnessBit16, sManager->bit16Len, PAR3,sManager->sendBrightnessBit16);
        delayUs(sManager->F3_T0);
        for(i = 0 ; i < dataLength-1;)
        {
            YX031UartsendPDMA(&data[i], 6, PAR3,&data2[i]);
            i=i+6;
            delayUs(sManager->F3_T1);
        }
        break;
    case 12:
		if((sManager->ICParameter.REG0[2]&0x38) == 0x08){
			YX031UartsendPDMA(sManager->sendBrightnessBit12, sManager->bit12Len, PAR3,sManager->sendBrightnessBit12);
			delayUs(sManager->F3_T0);
			for(i = 0 ; i < dataLength-1;)
			{
				YX031UartsendPDMA(&data[i], 5, PAR3,&data2[i]);
				i=i+5;
				delayUs(sManager->F3_T1);
			}		
		}
		else{
			YX031UartsendPDMA(sManager->sendBrightnessBit12, sManager->bit12Len, PAR3,sManager->sendBrightnessBit12);
			delayUs(sManager->F3_T0);
			for(i = 0 ; i < dataLength-1;)
			{
				YX031UartsendPDMA(&data[i], 9, PAR3,&data2[i]);
				i=i+9;
				delayUs(sManager->F3_T1);
			}
		}
        break;
    default:
        break;
    }
}

static void showState(void)
{
    UartPuts(UART_COM1, "State:\r\n");
	UartPrintf(UART_COM1, "uart double com = %d\r\n",sManager->UARTDoubleComEnable);
	UartPrintf(UART_COM1, "chipNum = %d\r\n",sManager->chipNum);
	UartPrintf(UART_COM1, "init num = %d\r\n",sManager->init_rep);
	UartPrintf(UART_COM1, "lowIq = %d\r\n",sManager->LP_EN);
	UartPrintf(UART_COM1, "lowIq time = %d\r\n",sManager->pdTime);
	UartPrintf(UART_COM1, "frame time = %d\r\n",sManager->frame.time);
    UartPrintf(UART_COM1, "buad1 = %d\r\n", sManager->uartParameter1.baudrate);
    UartPrintf(UART_COM1, "buad2 = %d\r\n", sManager->uartParameter2.baudrate);
    UartPrintf(UART_COM1, "buad3 = %d\r\n", sManager->uartParameter3.baudrate);
	
	UartPrintf(UART_COM1, "REG0_2 = %d\r\n", sManager->ICParameter.REG0_2[2]);
    UartPrintf(UART_COM1, "REG0 = %d\r\n", sManager->ICParameter.REG0[2]);
    UartPrintf(UART_COM1, "REG1 = %d\r\n", sManager->ICParameter.REG1[2]);
    UartPrintf(UART_COM1, "REG2 = %d\r\n", sManager->ICParameter.REG2[2]);
    UartPrintf(UART_COM1, "REG3 = %d\r\n", sManager->ICParameter.REG3[2]);
	UartPrintf(UART_COM1, "REG4 = %d\r\n", sManager->ICParameter.REG4[2]);

}

static void sendInitSqe(void)
{
    if (sManager->init_rep == 0) {
        return;
    }
    for (int i = 0; i < sManager->init_rep; i++)
    {
		sendOneInitSEQ();
    }
    
}


static void parInitFunc(uint8_t *data)
{
    int16_t index;
	uint8_t *p = data;
    index = StrGetCHIndex((char *)p, '-');
    if (index == -1) {
            UartPutsPDMA(UART_COM1, "init: No param");
            return;
    }
    else{
        if (strncmp((char *)&data[index + 1], sPar2Set, 3) == 0) {
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "init: No REP param");
				return;
			}
			p = p + index;
            sManager->init_rep = StrGetDec((char *)p, 0, 4);
			
			index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "init: No param");
				return;
			}
			p = p + index;
			sManager->chipNum = StrGetDec((char *)p, 0, 4);
            UartPrintf(UART_COM1, "set = %d\r\n", sManager->init_rep);
			UartPrintf(UART_COM1, "chipmun = %d\r\n", sManager->chipNum);
        }
        else if (strncmp((char *)&data[index + 1], sPar2Get, 3) == 0) {
            UartPrintf(UART_COM1, "init: get");
            UartPrintf(UART_COM1, "set = %d\r\n", sManager->init_rep);
			UartPrintf(UART_COM1, "chipmun = %d\r\n", sManager->chipNum);     
        }
        else if (strncmp((char *)&data[index + 1], sPar2send, 4) == 0) {
            UartPrintf(UART_COM1, "init: send");
			sendInitSqe();
        }
        else {
            UartPrintf(UART_COM1, "init: No param");
        }       
    }
}
static void sendFrameSqe(uint8_t pwmbit,uint8_t *pwmData,uint16_t pwmLen,uint8_t *pwmdata2)
{
	uint16_t ms;
    uint16_t us;
	sendOneInitSEQ();
	YX031UartsendPDMA(sManager->ICParameter.REG1, 4,PAR3,sManager->ICParameter.REG1);
	YX031UartsendPDMA(sManager->ICParameter.REG2, 4,PAR3,sManager->ICParameter.REG2);
	YX031UartsendPDMA(sManager->ICParameter.REG3, 4,PAR3,sManager->ICParameter.REG3);
	if(pwmbit == 16){
		sendBrightness(pwmbit,pwmData,pwmLen,pwmdata2);
	}
	else if(pwmbit == 12){		
		sendBrightness(pwmbit,pwmData,pwmLen,pwmdata2);	
	}
	UartIOToCore(UART_COM2, 0);
	UartTxPullDown(UART_COM2);
	UartIOToCore(UART_COM3, 0);
	UartTxPullDown(UART_COM3);
	delayUs(60);//60us
	UartIOToPeripheral(UART_COM2, 0);
	UartIOToPeripheral(UART_COM3, 0);
	sendVSYNC();
	delayUs(100);
	if(sManager->LP_EN == 1)
	{
		UartIOToCore(UART_COM2, 0);
		UartIOToCore(UART_COM3, 0);
		UartTxPullDown(UART_COM2);
		UartTxPullDown(UART_COM3);
		if (sManager->pdTime > 1000) {
			ms = sManager->pdTime / 1000;
			us = sManager->pdTime % 1000;
			vTaskDelay(ms);
			delayUs(us);
            }
            else {
                delayUs(sManager->pdTime);
            }
            UartIOToPeripheral(UART_COM2, 0);	
			UartIOToPeripheral(UART_COM3, 0);
	}
}

static void timerCallback(TimerHandle_t xTimer)
{
	xEventGroupSetBits(eventGroup, YX031_EVENT_FLASH);
	if (sManager->frame.time != sManager->frame.newTime) {
		if (sManager->frame.newTime) {
			xTimerChangePeriod(timerHandle, sManager->frame.newTime, 0);
			sManager->frame.time = sManager->frame.newTime;
		}
		else {
			xTimerStop(timerHandle, 0);
			vTaskSuspend(frameTaskHandle);
		}
	}
}

static void frameTask(void *parameter)
{
    static uint8_t frame = 0;
    
    while (1) {
        xEventGroupWaitBits(eventGroup, YX031_EVENT_FLASH, pdTRUE, pdTRUE, portMAX_DELAY);

        if (frame == 0) {
            frame++;
			FRAME_SEND_SEQ(sManager,frame);
        }
        else if (frame == 1) {
            frame = 0;
			FRAME_SEND_SEQ(sManager,frame);
        }
        else {
            UartPutsPDMA(UART_COM1, "frameTask ==> frame out of range\r\n");
            xTimerStop(timerHandle, 0);
            vTaskSuspend(frameTaskHandle);
        }	
    }
}

static void frameTimeTask(void *parameter)
{
	static uint8_t i=0;
	while (1) {
		if (sManager->frame.pwm12len != 0 || sManager->frame.pwm16len != 0) {
		}
		else {
			vTaskSuspend(frameTimeHandle);
		}
		sendInitSqe();
		FRAME_SEND_SEQ(sManager,i);	
		sManager->frame.time = sManager->frame.newTime;
		xTimerChangePeriod(timerHandle, sManager->frame.time, 0);
		if (eTaskGetState(frameTaskHandle) == eSuspended) {
			vTaskResume(frameTaskHandle);
		}
		vTaskSuspend(frameTimeHandle);
	}
}

static void parFrameFunc(uint8_t *data, uint16_t receiveLen)
{
    int16_t index,frameID,pwmbit,modle;
	uint8_t *p = data;
    index = StrGetCHIndex((char *)p, '-');
	receiveLen = receiveLen - index-12;
    if (index == -1) {
            UartPutsPDMA(UART_COM1, "init: No param");
            return;
    }
    else{
		// yx031 -frame -set frameId 16bit/12bit modle data1data2data3......data(num)
        if (strncmp((char *)&data[index + 1], sPar2Set, 3) == 0) {
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			receiveLen = receiveLen - index;
			if(index == -1){
				UartPutsPDMA(UART_COM1, "frame: No brightness param");
				return;
			}
			p = p+index;
			frameID = StrGetHex((char *)p, 0,1);
			UartPrintf(UART_COM1, "frame id:%d\r\n",frameID);
			index = StrGetNextNotSpace((char *)p);
			receiveLen = receiveLen - index;
			p=p+index;
			if(strncmp((char *)p, sPar16bit, 5) == 0){
				pwmbit = 16;
				UartPrintf(UART_COM1, "16bitdata\r\n");
			}
			else if(strncmp((char *)p, sPar12bit, 5) == 0){
				pwmbit = 12;
				UartPrintf(UART_COM1, "12bitdata:\r\n");
			}
			else {
				UartPrintf(UART_COM1, "err pwmbit par\r\n");
			}
			index = StrGetNextNotSpace((char *)p);
			receiveLen = receiveLen - index;
			p=p+index;
			if(strncmp((char *)p, sPar2SISO, 4) == 0){modle = 0;p=p+5;receiveLen = receiveLen -5;}
			else if(strncmp((char *)p, sPar2ABB, 3) == 0){modle =1;p=p+4;receiveLen = receiveLen -4;}
			else if(strncmp((char *)p, sPar21p1b, 4) == 0){modle =2;p=p+5;receiveLen = receiveLen -5;}
			else if(strncmp((char *)p, sPar23p1b, 4) == 0){modle = 3;p=p+5;receiveLen = receiveLen -5;}
			else {
				UartPrintf(UART_COM1, "err model par\r\n");
			}
			setBrightness(pwmbit,p,receiveLen,frameID,modle);
		}
        // yx031 -frame -get frameId 16bit/12bit
		else if (strncmp((char *)&data[index + 1], sPar2Get, 3) == 0) {
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			receiveLen = receiveLen - index;
			if(index == -1){
				UartPutsPDMA(UART_COM1, "frame: No brightness param");
				return;
			}
			p = p+index;
			if(strncmp((char *)p, sPar16bit, 5) == 0){
				for (int ana = 0; ana < sManager->frame.pwm16len; ana++) {
				UartPrintf(UART_COM1, "%2X ", sManager->frame.data16[ana]);
			}
			}
			else{
				UartPrintf(UART_COM1, "12bitdata:\r\n");
				for (int ana = 0; ana < sManager->frame.pwm12len; ana++) {
				UartPrintf(UART_COM1, "%2X ", sManager->frame.data12[ana]);			
				}
			}				
        }
        // yx031 -frame -send frameId 16bit/12bit
		else if (strncmp((char *)&data[index + 1], sPar2send, 4) == 0) {
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			receiveLen = receiveLen - index;
			if(index == -1){
				UartPutsPDMA(UART_COM1, "frame: No brightness param");
				return;
			}
			p = p+index;
			frameID = StrGetHex((char *)p, 0,1);
			
			index = StrGetNextNotSpace((char *)p);
			receiveLen = receiveLen - index;
			p=p+index;
			if(strncmp((char *)p, sPar16bit, 5) == 0){
				index = StrGetNextNotSpace((char *)p);
				receiveLen = receiveLen - index;
				p = p + index;
				if(frameID == 0){
					sendFrameSqe(16,sManager->frame.data16,sManager->frame.pwm16len,sManager->frame.b_data16);
				}
				else if(frameID == 1){
					sendFrameSqe(16,sManager->frame.data16_1,sManager->frame.pwm16len,sManager->frame.b_data16_1);
				}
			}
			else if(strncmp((char *)p, sPar12bit, 5) == 0){
				index = StrGetNextNotSpace((char *)p);
				receiveLen = receiveLen - index;
				p = p + index;
				if(frameID == 0){
					sendFrameSqe(12,sManager->frame.data12,sManager->frame.pwm12len,sManager->frame.b_data12);
				}
				else if(frameID == 1){
					sendFrameSqe(12,sManager->frame.data12_1,sManager->frame.pwm12len,sManager->frame.b_data12_1);
				}
			}
			UartPrintf(UART_COM1, "frame: send");
        }
        else {
            UartPrintf(UART_COM1, "frame: No param");
        }       
    }	
}

void parTimeFunc(uint8_t *data)
{
    int16_t index;
	uint8_t *p = data;
    index = StrGetCHIndex((char *)p, '-');
    if (index == -1) {
            UartPutsPDMA(UART_COM1, "time: No param");
            return;
    }
    else{
        if (strncmp((char *)&data[index + 1], sPar2Set, 3) == 0) {
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "time: No REP param");
				return;
			}
			p = p + index;			
			if(strncmp((char *)p, sPar16bit, 5) == 0){
				sManager->frame.dataBit = 16;
			}
			else if(strncmp((char *)p, sPar12bit, 5) == 0){
				sManager->frame.dataBit = 12;
			}
			else {
				UartPrintfPDMA(UART_COM1, "no PwmBit");
			}
			index = StrGetNextNotSpace((char *)p);
			p=p+index;
            sManager->frame.newTime = StrGetDec((char *)p, 0, 6);
			UartPrintfPDMA(UART_COM1, "time: pwmbit = %d time = %d\r\n",sManager->frame.dataBit ,sManager->frame.newTime);
			if (xTimerIsTimerActive(timerHandle) == pdFALSE) {
				if (sManager->frame.newTime == 0) {
					return;
				}
				if (eTaskGetState(frameTimeHandle) == eSuspended) {
					vTaskResume(frameTimeHandle);
				}
            }
			
            return;
        }
		else if(strncmp((char *)&data[index + 1], "t_time", 6) == 0){
			p = p + index;
            index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "time: No REP param");
				return;
			}
			p = p + index;	
			sManager->t_time = StrGetDec((char *)p, 0, 3);
			UartPrintfPDMA(UART_COM1,"time: t_time = %d\r\n",sManager->t_time);
		}
        else if(strncmp((char *)&data[index + 1], sPar2Get, 3) == 0){
			UartPrintfPDMA(UART_COM1, "time: frame time = %d\r\n", sManager->frame.newTime);
			UartPrintfPDMA(UART_COM1,"time: t_time = %d\r\n",sManager->t_time);
			UartPrintfPDMA(UART_COM1,"time: lowiq time = %d\r\n",sManager->pdTime);
		}
		else {
            UartPrintf(UART_COM1, "time: No param");
        }       
    }	
}
void setReg(uint8_t regAddress, uint8_t regVal)
{
	switch(regAddress)
	{
		case YX031_WRITE_REG0:
			sManager->ICParameter.REG0[2] = regVal;
			sManager->ICParameter.REG0[3] = CRC8MaxIM(sManager->ICParameter.REG0,3,1);
			break;
		case YX031_WRITE_REG1:
			sManager->ICParameter.REG1[2] = regVal;
			sManager->ICParameter.REG1[3] = CRC8MaxIM(sManager->ICParameter.REG1,3,1);
			break;
		case YX031_WRITE_REG2:
			sManager->ICParameter.REG2[2] = regVal;
			sManager->ICParameter.REG2[3] = CRC8MaxIM(sManager->ICParameter.REG2,3,1);
			break;
		case YX031_WRITE_REG3:
			sManager->ICParameter.REG3[2] = regVal;
			sManager->ICParameter.REG3[3] = CRC8MaxIM(sManager->ICParameter.REG3,3,1);
			break;
		case YX031_WRITE_REG4:
			sManager->ICParameter.REG4[2] = regVal;
			sManager->ICParameter.REG4[3] = CRC8MaxIM(sManager->ICParameter.REG4,3,1);
			break;
		default:
			break;
	}
}
	
void parRegFunc(uint8_t *data)
{
    int16_t index;
	uint8_t regAddress,regVal;
	UART_PAR par;
	uint8_t *p = data;
    index = StrGetCHIndex((char *)p, '-');
    if (index == -1) {
            UartPutsPDMA(UART_COM1, "REG: No param");
            return;
    }
    else{
        if (strncmp((char *)&data[index + 1], sPar2Set, 3) == 0) {
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "REG: No regAddress param");
				return;
			}
			p = p + index;
			if(strncmp((char *)p,"REG0_2",6) == 0){
				index = StrGetNextNotSpace((char *)p);
				p=p+index;
				sManager->ICParameter.REG0_2[2] = StrGetHex((char *)p, 0, 2);
				sManager->ICParameter.REG0_2[3] =CRC8MaxIM(sManager->ICParameter.REG0_2,3,1);
				UartPrintfPDMA(UART_COM1, "REG0_2: %2X\r\n",sManager->ICParameter.REG0_2[2]);
				return;
			}
            regAddress = StrGetHex((char *)p, 0, 2);
			
			index = StrGetNextNotSpace((char *)p);
			p = p + index;
			regVal = StrGetHex((char *)p, 0, 2);
			setReg(regAddress, regVal);
			UartPrintfPDMA(UART_COM1, "REG: 0x%2X = %2X\r\n", regAddress,regVal);
        }
		else if(strncmp((char *)&data[index + 1], sPar2Get, 3) == 0){
			UartPrintfPDMA(UART_COM1, "REG0= %2X\r\n",sManager->ICParameter.REG0[2]);	
			UartPrintfPDMA(UART_COM1, "REG1= %2X\r\n",sManager->ICParameter.REG1[2]);	
			UartPrintfPDMA(UART_COM1, "REG2= %2X\r\n",sManager->ICParameter.REG2[2]);	
			UartPrintfPDMA(UART_COM1, "REG3= %2X\r\n",sManager->ICParameter.REG3[2]);	
			UartPrintfPDMA(UART_COM1, "REG4= %2X\r\n",sManager->ICParameter.REG4[2]);	
		}
		else if(strncmp((char *)&data[index + 1], sPar2send, 3) == 0){
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "REG: No regAddress param");
				return;
			}
			p = p + index;
            regAddress = StrGetHex((char *)p, 0, 2);
			
			index = StrGetNextNotSpace((char *)p);
			p = p + index;
			par = (UART_PAR )StrGetHex((char *)p, 0, 2);
			switch (regAddress)
			{
				case YX031_WRITE_REG0:
					YX031UartsendPDMA(sManager->ICParameter.REG0,4,par,sManager->ICParameter.REG0_2);
					break;
				case YX031_WRITE_REG1:
					YX031UartsendPDMA(sManager->ICParameter.REG1,4,par,sManager->ICParameter.REG1);
					break;
				case YX031_WRITE_REG2:
					YX031UartsendPDMA(sManager->ICParameter.REG2,4,par,sManager->ICParameter.REG2);
					break;
				case YX031_WRITE_REG3:
					YX031UartsendPDMA(sManager->ICParameter.REG3,4,par,sManager->ICParameter.REG3);
					break;
				case YX031_WRITE_REG4:
					YX031UartsendPDMA(sManager->ICParameter.REG4,4,par,sManager->ICParameter.REG4);
					break;
				default:
					break;
			}
			UartPrintf(UART_COM1, "reg: send");
		}
        else {
            UartPrintf(UART_COM1, "reg: No param");
        }       
    }		
}

void parInterfaceFunc(uint8_t *data)
{
    int16_t index;
	struct uartParameter uartP;
	uint8_t par;
	uint8_t *p = data;
    index = StrGetCHIndex((char *)p, '-');
    if (index == -1) {
            UartPutsPDMA(UART_COM1, "REG: No param");
            return;
    }
    else{
        if (strncmp((char *)&data[index + 1], sPar2Set, 3) == 0) {
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "REG: No regAddress param");
				return;
			}
			p = p + index;
            par = StrGetDec((char *)p, 0, 2);
			
			index = StrGetNextNotSpace((char *)p);
			p=p+index;
			uartP.baudrate= StrGetDec((char *)p, 0, 8);
			
			index = StrGetNextNotSpace((char *)p);
			p=p+index;
			uartP.stopbit = StrGetHex((char *)p, 0, 2);	

			index = StrGetNextNotSpace((char *)p);
			p=p+index;
			uartP.intervalbit = StrGetHex((char *)p, 0, 2);				
			switch( par )
			{
				case PAR1:
					sManager->uartParameter1 = uartP;
					UartPrintfPDMA(UART_COM1,"F1");
					break;
				case PAR2:
					sManager->uartParameter2 = uartP;
					UartPrintfPDMA(UART_COM1,"F2");
					break;
				case PAR3:
					sManager->uartParameter3 = uartP;
					UartPrintfPDMA(UART_COM1,"F3");
					break;
				default:
					break;
			}
			UartPrintfPDMA(UART_COM1, "buad= %d stopbit = %d intervalbit = %d\r\n",uartP.baudrate,uartP.stopbit,uartP.intervalbit);			
        }
		else if(strncmp((char *)&data[index + 1], sPar2Get, 3) == 0){
			UartPrintfPDMA(UART_COM1, "buad1= %d stopbit = %d intervalbit = %d\r\n",sManager->uartParameter1.baudrate,sManager->uartParameter1.stopbit,sManager->uartParameter1.intervalbit);		
			UartPrintfPDMA(UART_COM1, "buad2= %d stopbit = %d intervalbit = %d\r\n",sManager->uartParameter2.baudrate,sManager->uartParameter2.stopbit,sManager->uartParameter2.intervalbit);		
			UartPrintfPDMA(UART_COM1, "buad2= %d stopbit = %d intervalbit = %d\r\n",sManager->uartParameter3.baudrate,sManager->uartParameter3.stopbit,sManager->uartParameter3.intervalbit);		
		}
		else if(strncmp((char *)&data[index + 1], sParDouble, 5) == 0){
			p = p + index;
			index = StrGetNextNotSpace((char *)p);
			p= p + index;
			if(strncmp((char *)p, "en", 2) == 0){
				sManager->UARTDoubleComEnable = 1;
				UartPrintfPDMA(UART_COM1, "double uart enable\r\n");	
			}
			else if(strncmp((char *)p, "unen", 4) == 0){
				sManager->UARTDoubleComEnable = 0;
				UartPrintfPDMA(UART_COM1, "double uart disable\r\n");
			}
			else{
				UartPrintfPDMA(UART_COM1, "double uart par err\r\n");
			}
		}
        else {
            UartPrintf(UART_COM1, "reg: No param");
        }       
    }	
}

void parLowIQ(uint8_t *data)
{
    int16_t index;
	uint8_t *p = data;
    index = StrGetCHIndex((char *)p, '-');
    if (index == -1) {
		UartPutsPDMA(UART_COM1, "REG: No param");
		return;
    }
    else{
		if (strncmp((char *)&data[index + 1], "en", 2) == 0){
			sManager->LP_EN = 1;
			UartPrintfPDMA(UART_COM1,"lowiq en\r\n");
		}
		else if (strncmp((char *)&data[index + 1], "unen", 4) == 0){
			sManager->LP_EN = 0;
			UartPrintfPDMA(UART_COM1,"lowiq unen\r\n");
		}
		else if (strncmp((char *)&data[index + 1], sParTime, 4) == 0){
			p=p+index;
            index = StrGetNextNotSpace((char *)p);
			if(index == -1){
				UartPutsPDMA(UART_COM1, "lowiq: time no\r\n");
				return;
			}
			p = p + index;
			sManager->pdTime = StrGetDec((char *)p, 0, 7);
			UartPrintfPDMA(UART_COM1,"lowiq time = %d us\r\n",sManager->pdTime);
		}
		else {
            UartPrintf(UART_COM1, "lowiq: No match param");
        }  
	}
}	

static void cmdYX031Callback(CmdParamTypeDef *param)
{
    uint16_t recelen = UartGetReceiveLen(UART_COM1);
    uint8_t *receiveArray = UartGetRxBuffer(UART_COM1);

    if (param == NULL) {
        taskENTER_CRITICAL();
        showState();
        taskEXIT_CRITICAL();
        return;
    }

    if (strcmp(param->name, sParInit) == 0) {
        parInitFunc(&receiveArray[param->index]);
    }
    else if (strcmp(param->name, sParFrame) == 0) {
		parFrameFunc(&receiveArray[param->index],UartGetReceiveLen(UART_COM1));
    }
	else if (strcmp(param->name, sParTime) == 0){
		parTimeFunc(&receiveArray[param->index]);
	}
	else if (strcmp(param->name, sParREG) == 0){
		parRegFunc(&receiveArray[param->index]);
	}
	else if(strcmp(param->name, sParInterface) == 0){
		parInterfaceFunc(&receiveArray[param->index]);
	}
	else if(strcmp(param->name, sParLowIQ) == 0){
		parLowIQ(&receiveArray[param->index]);
	}
}


void YX031AppInit(void)
{
    static uint8_t vsyncSeq[4] = {0x79,0x20,0x00,0xa0};
    static uint8_t sendBrightnessBit16[3] = {0x79,0x60,0x61};
    static uint8_t sendBrightnessBit12[3] = {0x79,0xa0,0xab};
	static uint8_t Reg0Seq[4] = {0x79,0x40,0x00,0xFA};
	static uint8_t Reg0_2Seq[4] = {0x79,0x40,0x00,0xFA};
	static uint8_t Reg1Seq[4] = {0x79,0x41,0x00,0x3E};
	static uint8_t Reg2Seq[4] = {0x79,0x42,0x00,0x6B};
	static uint8_t Reg3Seq[4] = {0x79,0x43,0x00,0xAF};
	static uint8_t Reg4Seq[4] = {0x79,0x44,0x00,0xC1};

	static uint8_t frame16Cache[3072]={0};
    static uint8_t frame16Cache1[3072]={0};
	static uint8_t frame12Cache[3072]={0};
    static uint8_t frame12Cache1[3072]={0};
	
	static uint8_t frame16Cache_1[3072]={0};
    static uint8_t frame16Cache1_1[3072]={0};
	static uint8_t frame12Cache_1[3072]={0};
    static uint8_t frame12Cache1_1[3072]={0};
	
	static uint8_t cache[3072]={0};
	
    UtilMemCreate(heap1, HEAP_1_SIZE, yx031Heap);
    sManager = (struct YX031ManagerType *)UtilMemMalloc(yx031Heap,sizeof(struct YX031ManagerType));
	sManager->Uartpar = PAR4;
    sManager->UARTDoubleComEnable = 0;
    sManager->ICParameter.REG0 = Reg0Seq;
	sManager->ICParameter.REG0_2 = Reg0_2Seq;
    sManager->ICParameter.REG1 = Reg1Seq;
    sManager->ICParameter.REG2 = Reg2Seq;
    sManager->ICParameter.REG3 = Reg3Seq;
    sManager->ICParameter.REG4 = Reg4Seq;
	
	sManager->frame.time = 100;
    sManager->frame.newTime = 100;
	sManager->frame.data16 = frame16Cache;
	sManager->frame.data12 = frame12Cache;
    sManager->frame.data16_1 = frame16Cache1;
    sManager->frame.data12_1 = frame12Cache1;
	sManager->frame.b_data12 = frame12Cache_1;
	sManager->frame.b_data12_1 = frame12Cache1_1;
	sManager->frame.b_data16 = frame16Cache_1;
	sManager->frame.b_data16_1 = frame16Cache1_1;
	sManager->frame.pwm12len = 0;
	sManager->frame.pwm16len = 0;
	sManager->frame.dataBit =16;
	
	sManager->LP_EN = 0;
	sManager->pdTime = 0;


    sManager->uartParameter1.baudrate = 1000000;
    sManager->uartParameter1.stopbit = 1;
    sManager->uartParameter1.intervalbit = 0;
    sManager->uartParameter2.baudrate = 375000;
    sManager->uartParameter2.stopbit = 1;
    sManager->uartParameter2.intervalbit = 0;
    sManager->uartParameter3.baudrate = 3000000;
    sManager->uartParameter3.stopbit = 1;
    sManager->uartParameter3.intervalbit = 0;

    sManager->initDelayT1 = 30;
    sManager->initDelayT2 = 5;
    sManager->initDelayT3 = 20;
    sManager->initDelayT4 = 5;

    sManager->F3_T0 = 1;
    sManager->F3_T1 = 1;
    sManager->t_time = 200;
    sManager->brightnessTime = 60;
    sManager->init_rep = 1;
    sManager->chipNum = 1;
    sManager->satrtByte1 = 0xF5;
    sManager->satrtByte2 = 0x80;

    sManager->vsyncSeq = vsyncSeq;
    sManager->vsyncLen = 4;
    sManager->sendBrightnessBit16 = sendBrightnessBit16;
    sManager->bit16Len = 3;
    sManager->sendBrightnessBit12 = sendBrightnessBit12;
    sManager->bit12Len = 3;

	sManager->cache = cache;
	GPIO_SetPullCtl(PH, BIT7, GPIO_PUSEL_DISABLE);
    GPIO_SetMode(PH, BIT7, GPIO_MODE_OUTPUT);
	PH7 =1;

    CmdAppend(sCmdYX031, cmdYX031Callback);
    CmdAppendParam(sCmdYX031, sParInit);
	CmdAppendParam(sCmdYX031, sParFrame);
	CmdAppendParam(sCmdYX031, sParTime);
	CmdAppendParam(sCmdYX031, sParREG);
	CmdAppendParam(sCmdYX031, sParInterface);
	CmdAppendParam(sCmdYX031, sParLowIQ);
}

void YX031CreateTask(uint8_t priorityLog, uint8_t priorityFrame)
{
    BaseType_t result = pdPASS;

	eventGroup = xEventGroupCreate();
    result = xTaskCreate(frameTask, "frameTask", 256, NULL, priorityFrame, &frameTaskHandle);
    if (result != pdPASS) {
        UartPutsPDMA(UART_COM1, "frameTask create fail\r\n");
    }
    else {
        vTaskSuspend(frameTaskHandle);
    }
	
	result = xTaskCreate(frameTimeTask, "frameTimeTask", 128, NULL, priorityFrame, &frameTimeHandle);
	if (result != pdPASS) {
		UartPutsPDMA(UART_COM1, "frameTimeTask create fail\r\n");
	}
	else {
		vTaskSuspend(frameTimeHandle);
	}

    timerHandle = xTimerCreate("031TimerTask", sManager->frame.time, pdTRUE, (void *)3, timerCallback);
    xTimerStop(timerHandle, 0);
}
